package hu.jonas.allunit.builder;

import hu.jonas.allunit.PluginHelper;
import hu.jonas.allunit.views.AllUnitViewPart;

import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

public class AllUnitProjectBuilder extends IncrementalProjectBuilder {

	public static final String ID = "hu.jonas.allunit.AllUnitBuilder";
	private TestFinder testFinder;
	private PluginHelper pluginHelper;
	
	public AllUnitProjectBuilder() {
		testFinder = new TestFinder();
		pluginHelper = new PluginHelper();
	}

	@SuppressWarnings("unchecked")
	@Override
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
			throws CoreException {
		
		pluginHelper.logInfo("%1$s is being built", getProject().getName());
		
		if (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD ||
				kind == IncrementalProjectBuilder.AUTO_BUILD) {
			
			if (testFinder.getTypesToBuilt().size() == 0) {
				doFullBuild();
			} else {
				doIncrementalBuild();
			}
		} else if (kind == IncrementalProjectBuilder.FULL_BUILD ||
				kind == IncrementalProjectBuilder.CLEAN_BUILD) {
			
			doFullBuild();
		}
		
		AllUnitViewPart view = pluginHelper.getAllUnitView();
		view.setNumberOfTests(getProject(), testFinder.getTypesToBuilt().size());
		
		pluginHelper.logInfo("%1$s has %2$d test(s)",
				getProject().getName(), testFinder.getTypesToBuilt().size());
		
		return null;
	}
	
	protected void doIncrementalBuild() throws CoreException {
		IResourceDelta delta = getDelta(getProject());
		if (delta != null) {
			delta.accept(testFinder);
		}
	}

	protected void doFullBuild() throws CoreException {
		testFinder.clearTypesToBuilt();
		getProject().accept(testFinder, IResource.DEPTH_INFINITE, false);
	}
	
	public TestFinder getTestFinder() {
		return testFinder;
	}

	public void setTestFinder(TestFinder testFinder) {
		this.testFinder = testFinder;
	}
	
}
